package net.maku.framework.common.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import java.io.*;
import java.util.List;
import java.util.Map;

public class EasyExcelUtils {
    /**
     * @param filePath 模板路径
     * @param excelType 导出excel类型
     * @param basic 基础数据填充
     * @param list 集合填充
     * @param mergeStrategy 自定义策略
     * @return
     */
    public static byte[] wrapDownloadExcel(String filePath, ExcelTypeEnum excelType, Map<String, Object> basic, List list, AbstractMergeStrategy mergeStrategy){
        ExcelWriter excelWriter = null;
        InputStream inputStream = null;
        ByteArrayOutputStream bos = null;
        try {
            inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath);
            bos = new ByteArrayOutputStream();
            excelWriter = EasyExcel.write(bos).withTemplate(inputStream).excelType(excelType).build();

            WriteSheet writeSheet = EasyExcel.writerSheet()
                    //自定义合并策略
                    .registerWriteHandler(mergeStrategy)
                    .build();

            // 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行，然后下面的数据往后移动。默认 是false，会直接使用下一行，如果没有则创建。
            // forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了，所以慎用
            // 简单的说 如果你的模板有list,且list不是最后一行，下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
            // 如果数据量大 list不是最后一行 参照下一个
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
            //列表属性填充
            if(basic != null) {
                excelWriter.fill(basic, fillConfig, writeSheet);
            }
            if(list != null) {
                excelWriter.fill(list, fillConfig, writeSheet);
            }

            //一定要进行关闭 才能获取bos
            excelWriter.finish();
            return bos.toByteArray();
        } catch (Exception e) {
            throw e;
        } finally {
            if (excelWriter != null) {
                excelWriter.finish();
            }
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
